View the updated 2022 version here.
Using IPTables on your Raspberry Pi
When exposing your device to the outside world you want to make sure you add a firewall this will keep nasty intruders out. This is not an “end-all” solution, but you want to limit access to ports people do not need access to. There are lots of solutions you could use as your firewall, most are built on top of Linux iptables. So we will just use iptables themselves.
sudo apt-get update
sudo apt install iptables-persistent -y
This will install iptables-persistent and any dependencies. Next, we need to set up some basic rules, please make sure to set up rules for the services you are using or you will be blocked from them by the firewall.
sudo iptables -F
sudo iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP
sudo iptables -A INPUT -p tcp ! --syn -m state --state NEW -j DROP
sudo iptables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP
sudo iptables -A INPUT -i lo -j ACCEPT
First please note all commands use sudo, you need higher privileges to add firewall rules. Using the above rules we block some basic attacks we will start adding rules to open specific ports we will use. So I will list the service and then the command to open the port. We could go more in-depth and allow connections only from certain IPs.
Allow SSH connections (*Important if you want to use SSH to manage your Pi*)
sudo iptables -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
Allow HTTP server
sudo iptables -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
Allow HTTPS server
sudo iptables -A INPUT -p tcp -m tcp --dport 443 -j ACCEPT
SMTP server
sudo iptables -A INPUT -p tcp -m tcp --dport 25 -j ACCEPT
sudo iptables -A INPUT -p tcp -m tcp --dport 465 -j ACCEPT
POP3 server
sudo iptables -A INPUT -p tcp -m tcp --dport 110 -j ACCEPT
sudo iptables -A INPUT -p tcp -m tcp --dport 995 -j ACCEPT
IMAP server
sudo iptables -A INPUT -p tcp -m tcp --dport 143 -j ACCEPT
sudo iptables -A INPUT -p tcp -m tcp --dport 993 -j ACCEPT
Home Assistant
sudo iptables -A INPUT -p tcp -m tcp --dport 8123 -j ACCEPT
You may have other services you want to accept connections to, we can add more rules for any port with a simple command just replace [TYPE] with the type of connection TCP, or UDP. Replace [PORT] with the port you will be accepting connections on.
sudo iptables -A INPUT -p [TYPE] -m [TYPE] --dport [PORT] -j ACCEPT
Finally, we need to allow outgoing connections we will need our machine to be able to update, use wget or other outside connections.
sudo iptables -I INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
sudo iptables -P OUTPUT ACCEPT && sudo iptables -P INPUT DROP
So now we have all our rules added, but do we actually? Let’s double-check by running the following:
sudo iptables -L -n
We can save the rules using iptables-persistent using:
sudo iptables-save >/etc/iptables/rules.v4
sudo ip6tables-save >/etc/iptables/rules.v6
And we are all done! Our system is more secure than it was before and it didn’t even take too long! Please note adding these rules is not a solution to solve all your problems. It just adds one more layer of security, finding open ports is half the battle when cracking a machine. Check out more security-related articles. You can also check out the man pages.